;;; Copyright (c) 1999 Massachusetts Institute of Technology
;;;
;;; This program is free software; you can redistribute it and/or
;;; modify it under the terms of the GNU General Public License as
;;; published by the Free Software Foundation; either version 3 of the
;;; License, or (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;; General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with this program; if not, see https://gnu.org/licenses or
;;; write to:
;;;  Free Software Foundatiom, Inc.
;;;  51 Franklin St, Fifth Floor
;;;  Boston, MA 02110-1301
;;;  USA

; I T S UTAPE SERVICE ROUTINE

UTBLKS==3

;UT CHANNEL STORAGE

EBLK
UTCHNT:	;BEG FOR GETSYS (UTAPE)
UTBFP:	REPEAT NUTIC+NUTOC,400000,,377	;L H BUFFER LINK PTR (INPUT PI)
		;RH  "   "  OUTPUT MAIN PROG
UTUSR:		;USER OR -1 IF FREE (LH)
UTUL:	REPEAT NUTIC+NUTOC,-1	;LINK TO CHANNEL ON SAME UTAPE OR -1(RH)
UTDIRP:	BLOCK NUTIC+NUTOC	;BYTE POINTER TO UTDIR
UTDBC:	BLOCK NUTIC+NUTOC	;RH BLCK COUNT CORRESP WITH UTDIRP
		;L H 3.1 3.5 READ FILE NO  4.9  ERROR  4.5 4.8 ERROR CNT
	;3.6 =0 FORD EXT =1 BACK EXT 3.7 4.2 PUT FILE NO
	;4.4 DELETE ON READ CLOSE
UTBFS:	BLOCK NUTIC+NUTOC	;BUFFERS IN USE 
UTLSTM:	BLOCK NUTIC+NUTOC	; TIME LAST BUF TAKEN BY PROG
UTMBN:	BLOCK NUTIC+NUTOC	; MN PROG ACTIVE BFFR NO OR -1,IF NO BUFFER ACIVE (LH)  
UTRAC:	BLOCK NUTIC+NUTOC+1	;ACTIVE  BUFFER NO PI  RH
			;FLAG TO MAIN PROG TP FULL (WRITE) RH
		;SIGN SET =>CHANNEL LOCKED
		;4.8 READ EOF REACHED AT PILEVEL OR CHNL CLOSED
		;EXTRA WORD FOR FILE DIR CHNL
		;4.7 DONT RELOAD AT PI
UTN1=.-NUTIC+1	
	BLOCK NUTOC
UTN2=.-NUTIC+1
	BLOCK NUTOC	;NAME OF FILE BEING WRITTEN
UTBKNP=.-NUTIC+1
	BLOCK NUTOC
MPRP:	BLOCK NUTIC+NUTOC	;MAIN PRGM BUFFER PNTR
MPRC:	BLOCK NUTIC+NUTOC	;CNT REMAINING
UTTNO:	BLOCK NUTOC+NUTIC	;TAPE NO (RH) 
			;LH CLOSE FLAG WRITE ORG FILE NO READ
UTEOF:	BLOCK NUTIC	;END OF FILE CHR

UTLDD:	BLOCK NUTIC+NUTOC+1	;IF -1, DC IS ACTUALLY SET UP AND TRANSFER CAN
				;BE EXPECTED IN LESS TAH 100 MS.
				;IF D CHANNEL LOCKED FLAG(4.9 UTRAC) WELL BE CHECKED
				;BEFORE GOING TO THE -1 STATE
				;EXTRA WORD FOR DIR CHNL
UTDERR:	BLOCK NUTIC+NUTOC+1	;4.9 ERROR 4.8 ABORT 4.7 UTAPE FULL

NUTCA:	0	;NUMBER UTAPE CHANNELS ACTIVE
NUWCA:	0	;# WRITE CHNLS ACT

UPCHFS:	0	;FAIR SHARE BFS PER CHNL

LUTWBF==40		;LENGTH OF BLK # PASSING LIST
UTWBF:	REPEAT LUTWBF,.+1	;LIST FOR PASSING BLK NOS FROM M.P. TO PI ON WRITE (INIT FS)
	0		;TERMINATOR FOR FS LIST
UTWBFS:	UTWBF		;FS PNTR

IFNDEF MXUTBF,MXUTBF==40 ;MAX BUFFERS FOR AN INPUT CHANNEL.

;TABLE AREAS

DEFINE TAG A
IRPS TAGX,,A
BBLK
TAGX:	0
EBLK
TERMIN
TERMIN

UTCH:	;BEG FOR GETSYS (UTAPE)
TAG ULCTM:,	REPEAT NUNITS,-1	;LAST TIME EUPOS RECOMPUTED
	;IF DG2=0.E. 0 THEN ACT POS =EUPOS+<TIME-ULCTM>*UDIR
TAG DRTM:,	REPEAT NUNITS,177777,,-1	;177777,,-1 => NO TIMING OP
			;N => DEAD RECKON UNTIL T=N

TAG UDIR:,	BLOCK NUNITS	;0=>STOP -1=>BACK 1=>FORW
IFN NEWDTP,	TAG OUDIR:,	BLOCK NUNITS	;DIR OF LAST OP
TAG UGOAL:,	REPEAT NUNITS,-1;POSIT GOAL OR -1 IF UNIT FREE
TAG EUPOS:,	BLOCK NUNITS	;ESTIMATED UNIT POSITION
			;SEE ULCTM IF DGW .NE. 1
TAG DCHNT:,	REPEAT NUNITS,-1;HEAD CHANNEL LIST OF UT OR -1 IF NO CHN ACT
TAG UMEMAD:,	IFE NEWDTP,REPEAT NUNITS, BLKO DC,	;GOAL MEMADR-1
		IFN NEWDTP,REPEAT NUNITS,BLKO DTC,
TAG URDWR:,	BLOCK NUNITS	;0 READ -1 WRITE(LOADED OPERATION)
TAG DG2:,	REPEAT NUNITS,-1;+ => ACCURATE
			;0 => EUPOS FAIRLY ACCURATE
			;-1 => DO NOT DEAD RECKON WITHOUT UTC
TAG UTASS:,	REPEAT NUNITS,0	;0 IF NOT ASSIGNED, SYSTEM NAME IF ASSIGNED
TAG UDIRO:,	REPEAT NUNITS,-1;ORGIN OF DIRECTORY
;OR -1 DIR NOT LOADED OR 4.9 DIR LOCKED OR 4.8+4.9 DIR DOUB LOCKED
;4.7 DIR CHANGED
;IF DIR LOCKED, IT MAY BE REFERENCED BUT NOT CHANGED
;4.5=0 => DIR AT LEAST ON WAY IN
;4.4=1 => TAPE IN UBLAT MODE


TAG UFLAPF:,	BLOCK NUNITS	;4.9 FLAPPING RQSTED OR IN PROGRESS
			;4.8 RQ TO ABORT FLAPPING
			;4.7 DRIVE ACTUALLY ON THE WAY
			;4.6 (TD10 ONLY) 0 PHASE 1 STOP   1 PHASE 1 STOP DONE
			;RH TIME TO STOP AFTER FLAPPED

TAG ULDCH:,	BLOCK NUNITS	;NUMBER OF LOADED CHANNEL IN LH
				;BUFFER NO OF DIR (INDEX INTO IOBFT) IN RH
			;LH 4.9 = LOW PRIORITY POSIT


TAG UDPWF:,	REPEAT NUNITS,-1	;DIRECTORY PAWED OVER FLAG

TAG UMNFB:,	BLOCK NUNITS	;MAIN PRGM FREE BLOCKS ON TAPE

TAG UTERP:,	BLOCK NUNITS	;LH ERROR CODE (CONI UTS,) RH # ERRORS

TAG UMNTR:,	BLOCK NUNITS	;UNAME OF LAST JOB TO READ IN DIRECTORY

SUNIT:	0	;SELECTED UNIT OR 0
IFE NEWDTP,	SUNITL:	0	;SAME _ 3
SMODE:	-1	;-1 POSIT 0 DATA
UIDLE:	-1	;-1 UTAPES COMPLETELY IDLE

IFN NEWDTP,	CUINT:	0	;-1 CLK HAS CAUSED BREAK
WRITE:	0	;0 READ -1 WRITE
TAPCNT:	0
TAP1:	0
TAP2:	0
TAP3:	0
UTTM1:	0	;UNIT COULD START IN SEARCH LOOP
UTTM2:	0	;MOST PRESSING UNIT SO FAR
UTTM3:	0	;TIME FOR ABOVE OR -1 IF NONE�
UTTM4:	0	;TAPE TO START FLAPPING (FLAG FLAP IN PROG IF NEWDTP=1)
IFE NEWDTP,[
UTTM5:	0	;TAPE TO STOP FLAPPING
FLPUNT:	0
]
UTENB:	0
LUTOTM:	0	;TIME OF LAST UT OPER
UTHERR:	0	;UT HANGUP ERR
USTSW:	0	;UT START SWITCH
UDCC:	0	;-1 IF UTAPE HAVE DC FOR BLK CYCLE
UTCHE==.-1	;END FOR GETSYS (UTAPE)

BBLK

;UTAPE CONTINUOUS NON-FILE IO

AUBL2:	CONO PI,UTCON	;DIRECTORY LOCKED, MAYBE ITS BEING FLAPPED
	PUSHJ P,UDELAY
AUBLAT:	XCTR XRW,[SKIPLE I,(J)]	;GET TAPE NUM, C(AC), SKIP IF NEG OR ZERO
	CAIG I,NUNITS	;SKIP IF TOO BIG
	 PUSHJ P,UTSNMK	;DON'T ALLOW UTAPE HACKERY UNLESS ASSIGNED
	  POPJ P,	;ERR EXIT, BAD TAPE NUM
	CONO PI,UTCOFF
	MOVE B,UDIRO(I)
	AOJE B,AUBL1	;DIR NOT IN
	TLNN B,10000
	JRST UTCONJ	;NOT IN UBLAT MODE
	JUMPL B,AUBL2
AUBL1:	MOVSI B,10000
	MOVEM B,UDIRO(I)
	CONO PI,UTCON
	JRST POPJ1

;.ASSIGN - ASSIGN A DECTAPE UNIT.
AASSIGN:XCTR XR,[MOVE I,(J)]
	CAILE I,NUNITS
	 POPJ P,
	JUMPLE I,CPOPJ
	MOVE A,UNAME(U)
	CONO PI,CLKOFF
	CAMN A,UTASS(I)
	 JRST CLKOJ1
	SKIPE UTASS(I)
	 JRST CLKONJ
	MOVEM A,UTASS(I)
	JRST CLKOJ1

ADESIGN:XCTR XR,[MOVE I,(J)]	;DEASSIGN UTAPE
	CAILE I,NUNITS
	POPJ P,
	JUMPLE I,CPOPJ
	SKIPN A,UTASS(I)
	JRST POPJ1
	CAME A,UNAME(U)
	POPJ P,
	SETZM UTASS(I)
	JRST POPJ1

;SET UTAPE NAME	;.UTNAM AC,	;LH(AC)=6BIT NAME, RH(AC)=TAPE #

AUTNAM:	XCTR XR,[MOVE Q,(J)]
	HRRZ I,Q	;GET TAPE #
	JUMPE I,CPOPJ	;TOO SMALL
	CAIG I,NUNITS	;TOO LARGE?
	 PUSHJ P,UTSNMK	;ASSIGNED TO SOMEONE ELSE?
	  POPJ P,	;YES, LOSE
	TLO D,1		;SET FLAG TO EXIT FROM OPEN ROUTINE
	PUSHJ P,UTO0	;GET DIR IN CORE, LOCK, ETC.
	TLNE TT,210000	;CHECK FOR DIRECTORY NOT READ IN, UBLAT MODE
	 JRST LSWPOP	;JUMP ON LOSSAGE
	HLRZ A,Q	;GET TAPE NAME
	AOSN UDPWF(I)	;DIRECTORY PAWED OVER YET?
	 PUSHJ P,UDPW	;NO, GO DO IT
	MOVE J,UDIRO(I)	;GET POINTER TO DIR
	XOR A,177(J)	;GET DIFF BETWEEN OLD & NEW NAMES
	TRNN A,-1	;IS THERE ANY?
	 JRST AUTN2	;NO, SKIP SOME CRUFT
	TLZ A,-1	;IGNORE DIFFERENCES IN LH
	XORM A,177(J)	;MODIFY NAME TO NEW NAME
	TLO J,100000	;SET DIR CHANGED BIT
AUTN2:	MOVEM J,UDIRO(I)	;STORE MODIFIED POINTER
	JRST LSWPJ1

UDPW:	HRRZ J,UDIRO(I)
	MOVEI TT,37
	DPB TT,[370500,,177(J)]
	ADD J,[500,,23.*2-1]
	MOVEI TT,0
UDPW2:	ILDB Q,J
	SKIPN Q
	 AOS TT
	CAIE Q,37
	 JRST UDPW2
	MOVEM TT,UMNFB(I)
	POPJ P,

;INITIALIZE UTAPE DIRECTORY	;.UINIT AC,	;C(AC)=TAPE #
;TAPE MUST BE ASSIGNED

AUINIT:	XCTR XRW,[SKIPLE I,(J)]	;TAPE # TOO LOW?
	 CAILE I,NUNITS	;OR HIGH?
	  POPJ P,	;YES
	PUSHJ P,UTSNMK	;OR NOT ASSIGNED TO THIS USER
	 POPJ P,
	TLO D,1		;SET EXIT FLAG FOR OPEN ROUTINE
	PUSHJ P,UTO0	;GET DIR, LOCK IT, ETC.
	TLNE TT,210000	;CHECK FOR UBLAT MODE, DIRECTORY NOT READ (TT=UDIRO(I))
	 JRST LSWPOP
	SETZM (TT)	;CLEAR FIRST LOC
	HRLI A,(TT)	;SET UP LH OF BLT POINTER
	HRRI A,1(TT)	;& RH
	BLT A,177(TT)	;ZAP
	MOVE A,[757367573674]	;GET WORD OF 7 5-BIT BYTES VALUE 36
	MOVEM A,56(TT)	;INDICATE FIRST 7 BLOCKS RESERVED
	MOVSI A,660000	;ONE 5-BIT BYTE, VALUE 33
	MOVEM A,67(TT)	;MARK FILE DIRECTORY BLOCK
	HRROS 177(TT)	;MARK END OF DIR
	SETZM UDPWF(I)	;INDICATE DIR PAWED OVER
	MOVEI A,559.	;# OF FREE BLOCKS IN EMPTY TAPE
	MOVEM A,UMNFB(I)	;STORE FOR FUTURE REFERENCE
	TLO TT,100000	;INDICATE CHANGED
	MOVEM TT,UDIRO(I)	;UPDATE POINTER
	JRST LSWPJ1

;UTAPE DISMOUNT

AUDISM:	XCTR XRW,[MOVE A,(J)]	;OPER 22
NFLAP:	JUMPLE A,CPOPJ
	CAILE A,NUNITS
	POPJ P,
	MOVSI C,-NUTIC-NUTOC
	CONO PI,UTCOFF
AUTDM1:	SKIPGE UTUSR(C)
	JRST AUTDM2
	HRRZ D,UTTNO(C)
	CAMN A,D
	JRST UTCONJ	;SOME ONE USING TAPE
AUTDM2:	AOBJN C,AUTDM1
	CONO PI,UTCON
	MOVSI C,(SETZ)
	IORM C,UFLAPF(A)
	JRST POPJ1

;ATTEMPTED DIRECTORY READ GOT FLUSHED
UTOLOS:	TLNE D,1	;CHECK EXIT FLAG
	JRST NULSET	;NOT .OPEN, SEIZE NOTHING AND RETURN
	JRST OPNL7	;.OPEN, SIGNAL DEVICE NOT READY

UTOF1:	MOVSI TT,200000
	IORM TT,UFLAPF(I)	;RQEST ABORT OF FLAP
	CONO PI,UTCON
	SKIPGE UFLAPF(I)
	PUSHJ P,UFLS	;HOPE FOR BEST
UTO:	PUSHJ P,UTSNMK	;MUST BE ASSIGNED
	 JRST NCA
	JUMPE I,OPNL1	;UTAPE OPEN
	CAILE I,NUNITS
	JRST OPNL1
UTO0:	CONO PI,UTCOFF
	SKIPGE UFLAPF(I)
	JRST UTOF1	;FLAPPING IN PROGRESS
	SKIPGE TT,UDIRO(I)
	AOSE TT
	JRST UTO4	;FILE DIR IN OR ON THE WAY
	MOVEI TT,200000
	MOVEM TT,DCHNT(I)
	MOVE TT,UNAME(U)
	MOVEM TT,UMNTR(I)	;TELL WHO FIRST CAUSED DIR TO BE READ IN
	MOVSI TT,20000
	ANDCAM TT,UDIRO(I)
UTO4:	CONO PI,UTCON
	MOVSI TT,400000
	MOVNI T,1
	PUSHJ P,LWAIT
	CAMLE T,UDIRO(I)	;WAIT FOR DIRECTORY TO COME IN OR GO OUT
	IORB TT,UDIRO(I)	;IF IN THEN LOCK IT
	CONO PI,UTCON
	CAMN TT,[-1]
	JRST UTOLOS	;DIDN'T GET READ IN
	PUSHJ P,SGNSET	;MAKE SUURE DIRECTORY GETS UNLOCKED ON PCLSR
	UDIRO(I)
	TLNE D,1	;CHECK SPECIAL EXIT FLAG
	POPJ P,		;EXIT
	TLNE TT,10000
	JRST UTOBL1	;IN UBLAT MODE
	AOSN UDPWF(I)
	PUSHJ P,UDPW
UDPW1:	TRNE D,200000
	JRST UTDEL1	;DELETE OR RENAME
	JUMPL D,UTOW1	;WRITE
	PUSHJ P,FLDRCK
	JRST UTO5B	;NORMAL FILE WANTED
	MOVEI J,0	;UTAPE DIRECTORY WANTED
	PUSHJ P,LSWPOP
	JRST LISTFE	;JOIN DIRECTORY CODE FOR OTHER DEVICES

UTOBL1:	CAIN W,4
	JRST OPNL4	;DELETE ILLEGAL IN UBLAT MODE
	CLEARB A,B
	JRST UTO8

UTO5B:	PUSHJ P,UTLK3	;MUST NOT CLOBBER TT
	JUMPE B,OPNL4
UTOW2:UTO8:	CONO PI,UTCON
	MOVSI TT,-NUTIC
	TLNE C,1
	MOVE TT,[-NUTOC,,NUTIC]
	SKIPL UTUSR(TT)
	AOBJN TT,.-1
	JUMPG TT,UNCA	;NO CHANNEL AVAILABLE
	CONO PI,UTCOFF
	SKIPL UTUSR(TT)
	JRST UTO8
	MOVEI J,DCHNT-UTUL(I)
	JRST .+2
UTO2:	MOVE J,Q
	HRRE Q,UTUL(J)
	JUMPGE Q,UTO2	;INSERT CHNL ONTO LIST FOR TAPE
	HRLOM U,UTUSR(TT)
	HRRM TT,UTUL(J)
	HRRZM I,UTTNO(TT)
	HRRZ J,UDIRO(I)
	ADD J,A
	MOVE Q,133(J)
	MOVEI J,EOFCH
	TRNN Q,1
	MOVEI J,141
	MOVEM J,UTEOF(TT)	;STORE EOF CHR
	SETZM UTDBC(TT)
	DPB A,[300500,,UTDBC(TT)]
	JUMPL D,UTOW3	;WRITE
	DPB A,[220500,,UTDBC(TT)]
UTOW4:	HRLM A,UTTNO(TT)
	HRRZ J,UDIRO(I)
	ADD J,[500,,23.*2-1]
	MOVEM J,UTDIRP(TT)
	MOVE J,[SETZ 377]
	MOVEM J,UTBFP(TT)
	CLEARM UTBFS(TT)
	MOVE J,TIME
	MOVEM J,UTLSTM(TT)
	HRROS UTMBN(TT)
	HLLOS UTRAC(TT)
	HRRZS UTRAC(TT)
	CONO PI,UTCON
	CLEARM MPRC(TT)
	AOS NUTCA
	PUSHJ P,FSCMP
	HRRZS UTRAC(TT)
	PUSHJ P,LSWPOP	;RELEASE FILE DIR
	MOVSS C
	HRL A,TT
	JSP Q,OPSLC7
	DNUACII,,DNUACCO	;ASCII UNITS INPUT ;ASCII UNITS OUTPUT
	DNUBKI,,DNUBKO	;BLOCK INPUT ;BLOCK OUTPUT
	DNUDTI,,DNUDTO	;WORD INPUT ;WORD OUTPUT
	DNUBKI,,DNUBKO	;BLOCK INPUT ;BLOCK OUTPUT

UTOW1:	SKIPN UMNFB(I)
	 JRST OPNL6	;FULL
	PUSH P,B
	PUSH P,A
	PUSHJ P,UTSNMK
	 JRST UTWNA	;NOT ASSIGNED
	SETZB A,B
	PUSHJ P,UTLK3
	JUMPE B,UFILDF	;FILE DIR FULL
	JRST UTOW2

UTSNMK:	SKIPN T,UTASS(I)	;TAPE MUST BE ASSIGNED TO THIS LOSER
	 POPJ P,
	CAME T,UNAME(U)
	CAMN T,USYSN1(U)
	 AOS (P)
	POPJ P,

UTOW3:	HRROM TT,1(B)	;RESERVE FILE NAME
	POP P,UTN1(TT)	;STORE NAMES
	POP P,UTN2(TT)
	MOVSI J,100000
	IORM J,UDIRO(I)	;SET FILE DIR MODIFYED
	MOVSI J,UTBKNP(TT)	;GET LIST PNTR PNTR
	MOVEM J,UTBKNP(TT)	;MAKE LH SELF-REFERENT SO INIT LINK WILL GO IN RH
	AOS NUWCA	;INCR # ACT UWRITE CHNLS
	JRST UTOW4

UNCA:	JUMPGE D,NCA
UTWNA:	SUB P,[2,,2]
NCA:	JRST OPNL10

UFILDF:	SUB P,[2,,2]
FILDF:	JRST OPNL5

S1NL14:	SUB P,[1,,1]
	JRST OPNL14

UDATAI:	SKIPA E,[444400,,1]
UASCII:	 MOVE E,[440700,,5]
	MOVEI B,UBLKI2
	JRST CHRKTI

UBLKI:	MOVE E,[444400,,1]
	JSP B,BLKT
UBLKI2:	MPRP(A)
	MPRC(A)
	UTBGB	;4.9 = 0 UTAPE 1 DISK
	UTBRB
	JRST 4,.
	SKIPG UTBFS(A)

;INPUT BLK BUFFER-GET RTN

UTBGB:	LDB Q,[IOLO,,UTBFP(A)]
	CAIN Q,377
	 JRST 4,.	;PNTRS OUT OF PHASE
	CAIN Q,376
	 JRST POPJ2	;END OF FILE
	CONO PI,UTCOFF
	SKIPL UTRAC(A)
	 SKIPGE IOBFT(Q)
	  JRST UTBGB1
	LDB J,[IOLO,,IOBFT(Q)]
	HRRM J,UTBFP(A)
	MOVEI TT,(SETZ)
	CAIL J,376
	 HRLM TT,UTBFP(A)
	CONO PI,UTCON
	SOS UTBFS(A)
UTBWG4:	MOVE J,TIME
	MOVEM J,UTLSTM(A)
	MOVEI J,-3
	DPB J,[IOLO,,IOBFT(Q)]
	LDB TT,[IOSA,,IOBFT(Q)]
	LSH TT,6
	HLL TT,E
	MOVEM TT,MPRP(A)
	MOVEI TT,200
	IMULI TT,(E)
	MOVEM TT,MPRC(A)
	HRLM Q,UTMBN(A)
	JRST POPJ1

UTBGB1:	CONO PI,UTCON
	SKIPL IOBFT(Q)
	 SKIPGE UTRAC(A)
	  PUSHJ P,UFLS		;REALLY?
	JRST UTBGB

UBLKO:	MOVE E,[444400,,1]
	JSP B,BLKT
UBLKO2:	SETZ MPRP(A)
	MPRC(A)
	UTBWG
	UTBWW
	JRST 4,.
	TRNA

UASCCO:	SKIPA E,[440700,,5]
UDATAO:	 MOVE E,[444400,,1]
	MOVEI B,UBLKO2
	JRST CHRKTO

;OUTPUT BLKT BUFFER-GET RTN

UTBWG:	MOVE Q,UTBFS(A)	;GET # BUFS IN CHNL
	IMUL Q,NUWCA	;SCALE TO # ACT UWRITE CHNLS
	CAIL Q,LUTWBF	;IF BEING TOO GREEDY WITH BLOCK LIST SPACE
	POPJ P,		;LOSE
	PUSH P,A
	PUSH P,B
	MOVE D,A
	HRRZ Q,UTBFP(D)
	CAIL Q,376
	JRST UTBWG1	;NO BUFS NOW RELOAD
	SKIPGE UTDBC(D)
	JRST POPBAJ	;CHNL IN ERR

UTBWG2:	HRRZ J,UTBFS(D)
	CAMG J,UPCHFS
	JRST UTBWG1
	PUSHJ P,TCALL
	JRST UIMRQ
	JRST POPBAJ
	PUSHJ P,TCALL
	JRST UTMGB
	JRST UTBWG2

UTBWG1:	HRRZ Q,UTTNO(D)
	SOSGE UMNFB(Q)
	JRST UTBWG5
	PUSHJ P,AOSSET
	UMNFB(Q)
	PUSHJ P,LSWTL	;WAIT FOR
	UDIRO(Q)	;DIR TO UNLOCK
	PUSH P,E	;SAVE E
	PUSHJ P,TCALL
	JRST IUTCONS
	JRST UTBWG6
	PUSH P,A	;SAVE A
	PUSH P,B
	PUSH P,C
	MOVE C,Q
	MOVE B,UDIRO(C)
	MOVEI E,0	;INDICATE ADVANCE TO UDIRAD
	PUSHJ P,UDOUT2	;ADV DIR PNTRS (SKIP LOCK CHECK IN UDIRAD)
	JRST 4,.	;SHOULDN'T GET HERE
	JRST UTPFUL	;NO ROOM FOR EXT
	PUSHJ P,LSWPOP	;UNLOCK DIR
	PUSHJ P,LSWDEL	;UNHACK UTFAOS
	POP P,C
	POP P,B
	POP P,Q		;GET BACK BUF #
	POP P,E		;RESTORE E
	POP P,B
	POP P,A
	AOS UTBFS(A)
	JRST UTBWG4

UTBWG5:	AOS UMNFB(Q)
	JRST IOCER9

UTBWG6:	PUSHJ P,LSWCLR	;UNLOCK DIR & ADJ BLK CNT
	POP P,E
	JRST POPBAJ

UTPFUL:	SUB P,[2,,2]
	POP P,A		;GET BACK BUF #
	PUSHJ P,BRTN	;RETURN BUF
	JRST IOCER9	;BARF ABOUT TAPE FULL

UTBWW:	HLRE Q,UTMBN(A)
	JUMPL Q,CPOPJ
	PUSHJ P,LWAIT	;WAIT FOR
	SKIPN UTWBFS	;SPACE IN BLK LIST & GET PNTR
	MOVE J,UTWBFS	;(DO NOT COMBINE WITH PRECEDING INST)
	HRRZ H,(J)	;GET PNTR TO NEXT FREE WD
	MOVEM H,UTWBFS	;UPDATE FS PNTR
	CONO PI,UTCON	;TURN ON UTC NOW TO MINIMIZE OFF TIME EVEN THOUGH OFF AGAIN LATER
	HRRZ D,UTDBC(A)	;GET NEXT BLK #
	MOVSM D,(J)	;PUT IN NEW WD
	HLRZ D,UTBKNP(A)	;GET PNTR TO LAST WD IN LIST
	HRRM J,(D)	;STORE LINK IN END OF LIST
	HRLM J,UTBKNP(A)	;UPDATE END PNTR
	MOVEI J,377
	IORM J,IOBFT(Q)
	SKIPGE UTTNO(A)
	 SOS IOBFT(Q)	;CHANGE TO EOF
	CONO PI,UTCOFF
	HLRE J,UTBFP(A)
	JUMPL J,UTBWW1
	DPB Q,[IOLO,,IOBFT(J)]

UTBWW2:	HRLM Q,UTBFP(A)
	CONO PI,UTCON
	HRROS UTMBN(A)
	POPJ P,

UTBWW1:	HRRM Q,UTBFP(A)
	JRST UTBWW2

UTOCL:	MOVSI Q,(SETZ)
	IORM Q,UTTNO(A)
	LDB E,[300600,,MPRP(A)]	;NOW FILL OUT BLOCK WITH EOF CHARS
	CAIN E,7
	 JRST UTOCL6
UTOCL1:	HRROI C,[EOFWRD]
	SKIPG MPRC(A)
	 JRST UTOCL2
	PUSHJ P,UDATAO
	JRST UTOCL1

UTOCL6:	HRROI C,UTEOF(A)
	SKIPG MPRC(A)
	 JRST UTOCL2
	PUSHJ P,UASCCO
	JRST UTOCL6
 
UTOCL2:	SKIPG MPRC(A)
	PUSHJ P,UTBWW	;MAKE SURE BUFFER WRITTEN OUT SINCE MAYBE GOT
			;PCLSRED FROM UTBWW DURING .IOT THAT JUST FILLED BUFFER
	PUSH P,R
	MOVE D,A
	SKIPE UTBFS(D)
	PUSHJ P,UFLS
	HRRZ C,UTTNO(D)
	PUSHJ P,LSWTL
	UDIRO(C)
	HRRZ Q,UTBFP(D)
	CAIL Q,376
	JRST UTOCL4	;NORMAL CLOSE
	MOVEI Q,%PIIOC	;ABORT WORKS
	IORM Q,PIRQC(U)
	MOVEI A,0
	HRROI B,(D)
	PUSHJ P,UDELETE
UTOCL5:	PUSHJ P,LSWPOP
	POP P,R
	SOS NUWCA	;DECR # ACT UWRITE CHNLS
	JRST UTOCL3

UTOCL4:	MOVE A,UTN1(D)
	MOVE B,UTN2(D)
	PUSHJ P,UDELETE
	LDB Q,[220500,,UTTNO(D)]
	LSH Q,1
	ADD Q,UDIRO(C)
	MOVE A,UTN1(D)
	MOVE B,UTN2(D)
	MOVEM A,-2(Q)
	MOVEM B,-1(Q)
	LDB Q,[220500,,UTTNO(D)]
	ADD Q,UDIRO(C)
	MOVEI A,1
	IORM A,133(Q)
	JRST UTOCL5


UTDEL1:	MOVE C,I	;DELETE
	SKIPE SRN3(U)
	JRST UTRN1	;RENAME
	PUSHJ P,UTSNMK
	JRST NCA
	PUSHJ P,UDELETE
	JUMPE TT,OPNL4
	JRST LSWPJ1


UTRN1:	JUMPE A,UTRN3	;RENAME OF OPEN FILE
	PUSHJ P,UTSNMK	;ALLOW RENAME OF OPEN FILE
	JRST NCA
	PUSHJ P,UTLOOK
	JUMPE B,OPNL14
	PUSH P,Q
	MOVE A,SRN3(U)
	MOVE B,SRN4(U)
	PUSHJ P,UTLOOK
	POP P,Q
	JUMPN B,OPNL13
	MOVE A,SRN3(U)
	MOVE B,SRN4(U)
	MOVEM A,0(Q)
	MOVEM B,1(Q)
UTRN4:	MOVSI A,100000
	IORM A,UDIRO(C)
	JRST LSWPJ1

UTRN3:	ADDI B,IOCHNM(U)
	HLRZ TT,(B)
	MOVE A,SRN3(U)
	MOVE B,SRN4(U)
	MOVEM A,UTN1(TT)
	MOVEM B,UTN2(TT)
	JRST UTRN4

UDELETE:	MOVEI TT,0	;TT=0 IF NOTHING DELETED + OTHERWISE
UDELA:	PUSHJ P,UTLOOK
	JUMPE B,CPOPJ	;TAPE NO IN C,FILE NAME IN A,B
	MOVEI E,NUTIC-1
UDELE4:	HRRZ J,UTTNO(E)
	SKIPL UTUSR(E)
	CAME J,C
	JRST UDELE3
	HLRZ J,UTTNO(E)
	CAME J,A
	JRST UDELE3
	MOVSI J,10000
	TDNE J,UTDBC(E)
	JRST UDELE3	;THIS IS LOSER WHO IS CLOSING FILE
	IORM J,UTDBC(E)
	CLEARM (Q)
	SETOM 1(Q)
	AOJA TT,CPOPJ

UDELE3:	SOJGE E,UDELE4
UDELE1:	CLEARM (Q)
	CLEARM 1(Q)
	MOVE J,A
	ADD J,UDIRO(C)
	MOVEI B,1
	ANDCAM B,133(J)
	MOVSI J,100000
	IORM J,UDIRO(C)
UDELE6:	HRRZ B,UDIRO(C)
	ADD B,[500,,23.*2-1]
	MOVEI J,0
UDELE2:	ILDB E,B
	CAMN E,A
	AOS UMNFB(C)
	CAMN E,A
	DPB J,B
	CAIE E,37
	JRST UDELE2
	MOVE B,A
	MOVEI A,0
	AOJA TT,UDELA


UTICL:	PUSH P,R
	MOVE D,A
	MOVSI C,200000
	IORM C,UTRAC(D)	;SET EOF
	MOVEI T,400000
	TDNN T,UTRAC(D)
	PUSHJ P,UFLS	;WAIT FOR ACTIVE BUFFER TO TRANSFER
	PUSHJ P,UTBRB1	;RETURN ACTIVE BUFFER MAIN PROG
	HLRZ A,UTTNO(D)
	MOVE B,UTDBC(D)
	TLNE B,10000
	PUSHJ P,UDELE5	;FINISH FILE DELETE
	POP P,R
UTOCL3:	HRRZ A,UTBFP(D)
UTICL2:	CAIL A,376
	JRST UTICL3
	LDB C,[IOLO,,IOBFT(A)]
	PUSHJ P,BRTN
	MOVE A,C
	JRST UTICL2

UTICL3:	PUSHJ P,UCPAT0	;UT CHANNEL PATCH OUT
	CLEARM UTDIRP(D)
	SETOM UTUSR(D)
	CLEARM (R)
	POPJ P,



UCPAT0:	HRRZ B,UTTNO(D)	;PATCH OUT CHANNEL
	MOVEI C,DCHNT-UTUL(B)
	CONO PI,UTCOFF
UCPAT2:	HRRE E,UTUL(C)
	JUMPL E,UTCOP
	CAMN E,D
	JRST UCPAT1
	MOVE C,E
	JRST UCPAT2

UCPAT1:	HRRZ E,UTUL(E)
	HRRM E,UTUL(C)
	SOS NUTCA
UTCOP:	JRST UTCONJ

UDELE5:	HRRZ C,UTTNO(D)
	PUSHJ P,LSWTL
	UDIRO(C)
	HLRZ Q,UTTNO(D)
	MOVE A,Q
	LSH Q,1
	ADD Q,UDIRO(C)
	SUBI Q,2
	PUSHJ P,UDELE1
	JRST LSWPOP

UTBRB1:	MOVE A,D
UTBRB:	PUSH P,A
	HLRE A,UTMBN(A)
	JUMPL A,POPAJ
	PUSHJ P,BRTN
	POP P,A
	HRROS UTMBN(A)
	POPJ P,

UTRL1:	JUMPE B,UTRLDR
	HRRZ B,UTBFP(D)
	CAIE B,377
	JRST JDB6C
UTRLDR:	LDB R,[270100,,UTDBC(D)]
	JUMPN R,UTRLD1
	SKIPL R,UDIRO(C)	;SPECIAL KLUDGE TO RUN FAST
	TLNE R,10000	;SKIPN ON NOT IN UBLAT MODE
	JRST UTRLD1
	LDB TT,[220500,,UTDBC(D)]
	ILDB B,UTDIRP(D)
	AOS UTDBC(D)
	CAME B,TT
	JRST UTRLD2
UTRLD3:	PUSHJ P,IUTCONS	;RTN BUFFER NO IN A
	JRST UTRLR1	;MEM LOCKED (OR SOMETHING)
	CLEARM URDWR(C)
	HRRZ B,UTDBC(D)	;GET BLK # TO READ
	JRST UTRLD

UTRLD2:	CAIN B,37
	PUSHJ P,UAR

UTRLD1:	PUSHJ P,UDIRAD
	JRST JDB6C2	;DIR DOUBLE LOCKED
	JRST UTREOF
	JRST UTRLD3


JDDTA:	HLRZ D,ULDCH(C)	;FINISHED DATA TRANS TAPE IN C GET CHNL NO
	CLEARM UTLDD(D)
	SETOM SMODE
IFE NEWDTP,	CONSZ DC,7
IFN NEWDTP,	CONSO DTS,100000
	JRST UDATER	;DC STILL ENABLED => ERROR
	SETOM UGOAL(C)
	CAIL D,NUTIC
	JRST JDDT1	;WRITE OR FILE DIRECTORY
	MOVE E,UTRAC(D)
	HLLOS UTRAC(D)
	MOVEI B,377
	IORM B,IOBFT(E)
	HLRE B,UTBFP(D)
	JUMPL B,JDDT5
	DPB E,[IOLO,,IOBFT(B)]
JDDT6:	HRLM E,UTBFP(D)
	AOS UTBFS(D)


JDDT2:	PUSHJ P,JDB6W
	JRST JDDT3	;SAME TAPE CAN RELOAD, DONT CHECK OTHERS
JDDT4:	HRRZS ULDCH(C)
IFE NEWDTP,	JRST JDB4A	;UNIT NOW IDLE STOP IT
IFN NEWDTP,[
	PUSHJ P,JDSTP
	JRST JDB3
]

JDDT1:	CAIL D,NUTIC+NUTOC
	JRST UDRDD3	;FILE DIR IN OR OUT
	HRRZ A,UTRAC(D)
	PUSHJ P,IBRTN
	HLLOS UTRAC(D)
	SOS UTBFS(D)
	JRST JDDT2


JDDT5:	HRRM E,UTBFP(D)
	JRST JDDT6
UTREOF:	MOVSI E,200000
	IORM E,UTRAC(D)
	HLRE E,UTBFP(D)
	SKIPL E
	SOSA IOBFT(E)	;TURN END OF LIST TO END OF FILE
	SOS UTBFP(D)
	AOS UTBFS(D)	;TO START MAIN PROG
	JRST JDB6C

JDB6W:	HRRE D,DCHNT(C)
	JUMPL D,JDB6W1	;NO CHANNELS ACTIVE
	CAIN D,200000
	JRST UDRDD	;READ FILE DIR
JDB6C1:	SKIPL E,UTRAC(D)
	 TLNE E,300000
	  JRST JDB6C2	;CHANNEL LOCKED
	CAIL D,NUTIC
	 JRST JDB6A	;WRITE CHANNEL
	HRRZ B,UTBFS(D)
	CAILE B,MXUTBF	;READ CHANNEL; SHOULDN'T LET IT GET TOO MANY BUFFERS.
	 JRST JDB6C
	HRRZ B,UTFS
	CAIN B,377
	 JRST JDB6E	;TRY TO GET MORE MEMORY
	MOVE B,UTBFS(D)
	SOJLE B,UTRL1	;RELOAD CHANNEL WITH ONE OR NO BUFFERS
	MOVE B,UTLSTM(D)
	SUB B,TIME
	CAMG B,[-300.]
	 JRST JDB6C2	;NO RELOAD
JDB6F:	HRRZ B,UTBFS(D)	;NUMBER BUFS THIS CHANNEL HAS
	CAMGE B,UPCHFS
	 JRST UTRLDR
JDB6E:	PUSHJ P,UIMRQ	;TRY TO GET MORE MEMORY (IO)
	 JRST JDB6C2	;NOT AVAIL
	PUSHJ P,UTMGB	;ADD TO MEM ALLOC UTAPE
	JRST JDB6F

UTRLR1:	PUSHJ P,UDIRR	;BACK UP
	 JRST 4,.
	JRST 4,.	;LOSSAGE
JDB6C2:
JDB6C:	HRRE D,UTUL(D)
	JUMPGE D,JDB6C1
	JRST POPJ1

JDB6W1:	LDB D,[410300,,UDIRO(C)]
	SOJN D,POPJ1	;DIR CHANGED AND NOT LOCKED
	HRRZ D,UDIRO(C)
	LDB D,[370500,,177(D)]
	CAIE D,37
	JRST 4,.	;DIRECTORY CLOBBERED SINCE READ IN
	MOVEI D,100	;INITIATE FILE DIR WRITE
	SKIPL ULDCH(C)	;SKIPN ON ALREADY LOW PRIORITY POSIT
	PUSHJ P,ILLP	;INITIATE  LOW PRIOR POSIT
	JRST POPJ1

ULLP1:	SKIPGE UDIRO(C)
	POPJ P,
	SETOM URDWR(C)	;SET FILE DIR WRITE CYCLE FROM LOW PRIORITY CYCLE
	MOVSI D,400000	;LOCK DIR
	IORM D,UDIRO(C)
	MOVEI D,NUTIC+NUTOC
	HRRZ A,ULDCH(C)	;BUFFER NO OF DIRECTORY
	JRST JDB6W2


JDB6A:	HRRZ A,UTBFP(D)
	CAIGE A,376
	SKIPGE IOBFT(A)
	JRST JDB6C2	;LOCKED OUT SNIFFLE
	MOVE E,UTBKNP(D)	;GET BLK LIST PNTR
	MOVE J,UTWBFS
	EXCH J,(E)
	HRRZM E,UTWBFS
	HLRZ B,J	;GET BLK # FROM HEAD OF LIST
	HRR E,J		;SET LINK TO NEXT WD IN LIST
	TRNN E,-1	;IF LIST EMPTY
	MOVSI E,UTBKNP(D)	;SET END PNTR TO PNTR SO NEXT LINK WILL GO HERE
	MOVEM E,UTBKNP(D)	;UPDATE PNTR
	SETOM URDWR(C)
	HRRZ A,UTBFP(D)
	LDB E,[IOLO,,IOBFT(A)]
	HRRM E,UTBFP(D)
	MOVEI J,(SETZ)
	CAIL E,376
	HRLM J,UTBFP(D)

UTRLD:	HRRM A,UTRAC(D)
UDRR2:	MOVEM B,UGOAL(C)
	MOVEI B,-4
	DPB B,[IOLO,,IOBFT(A)]
	LDB B,[IOSA,,IOBFT(A)]
	LSH B,6
	SOS B
	HRRM B,UMEMAD(C)
	HRLM D,ULDCH(C)
	MOVE B,TIME
	MOVEM B,DRTM(C)
	POPJ P,

JDB6:	PUSHJ P,JDB6W
	JRST JDBRK7	;SUCCESFUL RELOAD
	SKIPL ULDCH(C)
IFE NEWDTP,[
	JRST JDBRK4	;CAN NOT RELOAD
	JRST JDF2A
]
IFN NEWDTP,[
	JRST JDBRK6
	JRST JDS1
]

UDRDD:	MOVE D,UDIRO(C)	;TAPE WANTS FILE DIRECTORY READ
	TLO D,20000	;OK FOR 4.5 CLEAR
	AOSE D		;REST SHOULD BE -1
	 JRST 4,.	;FILE DIRECTORY READ REQUEST WHEN ALREAD IN
	MOVEI D,NUTIC+NUTOC	;GET DIRECTORY CHANNEL NUMBER IN D
	PUSHJ P,IUTCONS
	 JRST POPJ1	;NO MEM
	LDB B,[IOSA,,IOBFT(A)]	;GET ORIGIN _ -6
	LSH B,6
	TLO B,600000	;SET LOCK, DOUBLE LOCK BITS
	MOVEM B,UDIRO(C)	;STORE ORIGIN
	HLLOS DCHNT(C)	;NO CHANNEL ACTIVE THIS UNIT YET
	CLEARM URDWR(C)	;SIGNAL WANT READ
	HRRM A,ULDCH(C)	;STORE BUFFER NUMBER
JDB6W2:	MOVEI B,100	;DIRECTORY BLOCK NUMBER
	JRST UDRR2

UDRDD3:	HRRZ D,ULDCH(C)	;FILE DIR IN OR OUT
	HRRZS UDIRO(C)	;UNLOCK DIRECTORY
	DPB C,[IOLO,,IOBFT(D)]
	HRRZS ULDCH(C)
	JRST JDDT2
UDIRAD:	TDZA E,E	;ADVANCE DIR PNTRS OF CHANNEL IN D
UDIRR:	MOVEI E,1	;REV DIR PNTRS THIS WINS FOR READS ONLY HA HA
	SKIPGE B,UDIRO(C)
	JRST UDOUT3
UDOUT2:	TLNE B,10000
	JRST UDBL1	;UBLAT MODE
UDOUT7:	LDB R,[270100,,UTDBC(D)]
	XOR R,E
	MOVEI Q,0
	CAIL D,NUTIC
	MOVEI Q,UTBLKS
	LDB TT,[220500,,UTDBC(D)]

UDIR1:	PUSHJ P,UITAB(R)
	TRNE J,-1	;BLK NO RTN IN RH J
	CAIN B,37
	JRST UDOUT	;END OF EXTENSION
	CAME B,TT
	SOJA Q,UDIR1
	SOJG Q,.-1
	LDB B,[300500,,UTDBC(D)]
	DPB B,UTDIRP(D)
UDARET:	JRST POPJ2

UDBL1:	AOS A,UTDBC(D)
	CAILE A,1101
	JRST POPJ1	;EOF
	JRST POPJ2

UDOUT:	JUMPN E,UDOUT5
	CAIL D,NUTIC
	JRST UDOUT1
	MOVEI A,0	;READ
	MOVE B,TT
	PUSHJ P,UTLOOK	;TAP NO IN C NAME IN A,B
	JUMPE B,POPJ1	;EOF OR ADR OF FIRST WD
UDOUT6:	DPB A,[220500,,UTDBC(D)]	;FILE NO
UDOUT4:	DPB A,[300500,,UTDBC(D)]
	MOVSI A,1_5
	XORM A,UTDBC(D)
	JRST UDOUT7


UDOUT3:	TLNN B,200000	;DIRECTORY DOUBLE LOCKED
	CAIL D,NUTIC
	POPJ P,
	JRST UDOUT2

UDOUT1:	SETZB A,B
	PUSHJ P,UTLOOK
	JUMPE B,UDOUT8	; FILE DIR FULL
	LDB J,[300500,,UTDBC(D)]
	MOVEM J,1(B)
	JRST UDOUT4

UDOUT8:	XORI R,1	;REVERSE DIR
	AOS (P)	;SKIPN ONCE
	JRST UITAB(R)	;BACK UP PNTRS AND RETURN

UDOUT5:	LDB A,[220500,,UTDBC(D)]
	LSH A,1
	ADD A,UDIRO(C)
	SKIPE -2(A)
	JRST UDARET
	MOVE A,-1(A)
	JRST UDOUT6

UTLK3:	SKIPA Q,UDIRO(I)
UTLOOK:	MOVE Q,UDIRO(C)	;B=0 => NOT FOUND
	HRLI Q,-23.
	PUSH P,[1]
UTLK2:	CAMN A,(Q)
	CAME B,1(Q)
	AOJA Q,UTLK1
	MOVE B,Q
	JRST POPAJ

UTLK1:	AOS(P)
	AOBJN Q,UTLK2
	MOVEI B,0
	JRST POPAJ

UITAB:	AOSA J,UTDBC(D)
	JRST UAR

UAF:	ILDB B,UTDIRP(D)
	POPJ P,

UAR:	MOVSI B,50000
	ADD B,UTDIRP(D)
	SKIPGE B
	SUB B,[430000,,1]
	MOVEM B,UTDIRP(D)
	LDB B,B
	SOS J,UTDBC(D)
	POPJ P,

EBLK
IFN NEWDTP,{
; T S UTAPE ROUTINES PI SERV (NEW UTAPE CONTROL)

TAPE:	0
UTP1:	0	;JRST PIPOS OR DATAI DC, OR JRST UTP3

BBLK

	SOS .-1
	AOSGE TAPCNT
	JRST 12,@TAPE

UTP3:	CONO DTS,770001
	JRST 12,@TAPE

PIPOS:	MOVEM A,TAP1
	MOVEM B,TAP2
	MOVEM C,TAP3
	MOVE C,SUNIT
	DATAI DTC,B
	TDZE B,[1777#-1]
	JRST PIPOS7
	MOVEM B, EUPOS(C)
	HRRZM C, DG2(C)
	SKIPGE UGOAL(C)
	JRST PIPF1
	SUB B,UGOAL(C)
	JUMPE B,PIPOS2
	ADD B,UDIR(C)
	MOVMM B,UTENB
	SKIPGE ULDCH(C)
	JRST PIPOS3
	JUMPN B,PIPOS3
PIPOSL:	MOVEI A,40000+DCCHN_3
	DPB C,[110300,,A]	;SET SELECTED UNIT CONO DTC,FOO(A)
	MOVE B,UDIR(C)
	XCT UTST2(B)
PIPOS5:	MOVE C,TAP3
	MOVE B,TAP2
	MOVE A,TAP1
	JRST 12,@TAPE

PIPOS7:	AOS BDBLKC
	JRST PIPOSL

EBLK

BDBLKC:	0
BBLK

PIPOS3:	MOVE A,UDIR(C)
	LSH A,2
	SUB B,A
	XOR B,UDIR(C)
	MOVEI A,40000
	DPB C,[110300,,A]
	JUMPG B,PIPOS4	;GOING WRONG DIR
PIPOS6:	MOVE B,TIME
	MOVEM B,ULCTM(C)
	ADD B,UTENB
	MOVEM B,DRTM(C)
PIPF2:	MOVE B,UDIR(C)
	TRNN A,40000
	TRO A,30000
	XCT  UTST2(B)
;	CLEARM UDCC
;	SETOM DCFREE
	CONO DTS,770001	;ENABLE ALL INTERUPTS AND SET FUNCTION STOP
	JRST PIPOS5

PIPF1:	MOVEI A,40000
	DPB C,[110300,,A]
	MOVE B,TIME
	MOVEM B,ULCTM(C)
	JRST PIPF2
PIPOS4:	TRZ A,40000	;TURN TAPE AROUND
	CLEARM DG2(C)
	MOVNS B,UDIR(C)
	MOVEM B,OUDIR(C)
	JRST PIPOS6

PIPOS2:	HLRZ A,ULDCH(C)
	SKIPL ULDCH(C)
	SKIPGE UTRAC(A)
	JRST PIPOS3	;CHANNEL LOCKED
	SETOM UTLDD(A)	;CHANNEL ACTUALLY LOADED TRANSFER IMMINENT
	AOS SMODE
	MOVEI A,0
	MOVE B,UMEMAD(C)
	SKIPGE URDWR(C)
	TROA A,400	;WRITE
	TLZ B,(BLKO-BLKI)
	SKIPL UDIR(C)
	JRST TAPFOR
	TRO A,100000
	ADD B,[DATAI-BLKI 200]
	MOVEM B,UTP1
	MOVNI B,200
	MOVEM B,TAPCNT

TAP4:	CONO DTC,300+DCCHN_3+UTCCHN(A)
	CONO DTS,770000
	MOVE B,URDWR(C)
	MOVEM B,WRITE
	MOVE C,TAP3
	MOVE B,TAP2
	MOVE A,TAP1
	JRST 12,@TAPE

TAPFOR:	TRO A,200000
	HRRM B,TAPCNT
	HRRI B,TAPCNT
	MOVEM B,DCMLOC
	MOVE B,[-200,,UTP3]
	HRRM B,UTP1
	HLLM B,TAPCNT
	JRST TAP4
UTERR:	CONI DTS,E
	SKIPL SMODE
	JRST UDATER
;	SKIPGE UDCC
;	SETOM DCFREE
UTER5:	SKIPN C,SUNIT
	JRST JDB3
	SETOM DG2(C)
	SKIPL UFLAPF(C)
	JRST UTER6
	CLEARM UFLAPF(C)
	CLEARM EUPOS(C)
	CLEARM UDIR(C)
	CLEARM OUDIR(C)
	CONO DTC,400000	;STOP DRIVE
	JRST JDB3

UTER6:	AOS UTERP(C)
	HRLM E,UTERP(C)
	TRNN E,20000
	JRST JDB3	;END ZONE
	MOVNS B,UDIR(C)
	MOVEI A,0
	SKIPGE B
	MOVEI A,1103
	MOVEM A,EUPOS(C)
	MOVE A,TIME
	MOVEM A,ULCTM(C)
	MOVEM A,DRTM(C)
	JRST JDB7

UDATER:	CONO DTS,770001	;ENABLE ALL INTERUPTS AND STOP FUNCTION
	SETOM SMODE
	HLRZ D,ULDCH(C)
	CLEARM UTLDD(D)
	JRST JDB3
UTCB0:	MOVE C,SUNIT
	AOSE CUINT	;SKIP IF CLOCK CAUSED INTERUPT
	JRST JDBRK	;NOT TIME FLAG
UTCB1:	MOVE B,UDIR(C)
	AOSN UTHERR	;HANG UP ERROR SENT FOR SLOW CLOCK ROUTINE
	JRST UTERR
	JRST JDB3

JDDT3:	MOVE A,EUPOS(C)	;AFTER DATA XFER
	SUB A,UGOAL(C)
	MOVMS E,A
	ADD A,TIME
	MOVEM A,DRTM(C)
	MOVE C,[-NUNITS,,1]
	MOVM B,DRTM(C)
	CAMGE B,TIME
	JRST JDB3	;SOMETHING ELSE DUE
	AOBJN C,.-3
	MOVE C,SUNIT
	SOJLE E,JDB7	;RELOADING FOR NEXT BLOCK
	JRST JDB3
ILLP:	MOVEM D,UGOAL(C)	;LOW PRIORITY POSIT ENTRY
	MOVSI A,(SETZ)
	IORM A,ULDCH(C)

UTDC:	SKIPGE UGOAL(C)
	POPJ P,	;UNIT IDLE
	SKIPGE DG2(C)
	JRST UTDC3
UTDC1:	MOVE A,EUPOS(C)	;ESTIMATE UNIT TIME AND UPDATE EUPOS
	SKIPG DG2(C)	;SKIP ON EXACT POS KNOWN
	SKIPN UDIR(C)	;SKIP ON UNIT RUNNING
	JRST UTDC4
	MOVE B,TIME
	SUBM B,ULCTM(C)
	EXCH B,ULCTM(C)
	IMUL B,UDIR(C)
	ADD A,B	;ACTUAL ESTIMATED POSITION
	MOVEM A,EUPOS(C)	;UPDATE EUPOS
UTDC4:	SUB A,UGOAL(C)
	MOVM B,A
	CAIG B,2
	JRST UTDC2
	ADD A,UDIR(C)
	MOVMS A�	
	CAMLE A,B
	SETZB A,B	;GOING WRONG DIR
UTDC2:	CAILE B,200.
	MOVEI B,200.	;LIMIT LONGEST DEAD RECKON
	ADD B,TIME
	MOVEM B,DRTM(C)
	POPJ P,

UTDC3:	MOVEI B,0	;NOT KNOWN EXACT POS REQUIRES IMMEDIATE ATTENTION
	JRST UTDC2

JDBRK:	CONSZ DTC,7
	CONSO DTS,2
	JRST POPRET
	CONSZ DTS,670300
	JRST UTERR
	CONSO DTS,100000
	JRST POPRET
	SKIPL SMODE
	JRST JDDTA	;DATA MODE
JDB3:
;	SKIPGE UDCC
;	SETOM DCFREE
	HRLOI B,177777
	MOVEM B,UTTM2
	SETZM UTTM4
	SETOM UTTM3	;UNIT MOST URGENT
	CLEARM UTTM1	;UNIT COULD START
	MOVE C,[-NUNITS,,1]
JDBRK7:	SKIPGE B,UFLAPF(C)
	JRST JDF1	;FLAPPING OP
JDF2:	SKIPL ULDCH(C)	;SKIP ON LOW PRIOR POSIT
	SKIPGE UGOAL(C)
	JRST JDB6	;UNIT FREE
JDS1:	SKIPE UDIR(C)
	JRST JDBRK4
	SKIPN UTTM1	;UNIT TO START
	HRRZM C,UTTM1
	JRST JDBRK6
JDBRK4:	MOVE B,DRTM(C)
	SUB B,TIME
	MOVE E,B
	SUB E,UTTM2	;TIME SOME OTHER UNIT NEEDS ATTN
	JUMPL B,JDCV1	;ALREADY OVERDUE
	MOVM D,E
	CAIG B,20.	;CONFLICT MORE THAN 20 BLKS AWAY
	CAIL D,20.	;THEY ARE SEPARETED BY 20 BLKS
	JRST JDCV1
	HRRZS C	;RELIEVE CONFLICT BY STOPPING UNIT DUE LATEST
	CAMG B,UTTM2
	HRRZ C,UTTM3
JDF5:	PUSHJ P,JDSTP	;STOP UNIT
	JRST JDB3

JDCV1:	JUMPGE E,ULLP
	MOVEM B,UTTM2	;UNIT DUE SOONEST
	HRRZM C,UTTM3
ULLP:	SKIPL ULDCH(C)
	JRST JDBRK6
	MOVE B,TIME	;LOW PRIORITY POSIT IN PROGRESS
	SUB B,ULCTM(C)
	IMUL B,UDIR(C)
	SKIPE DG2(C)
	MOVEI B,0
	ADD B,EUPOS(C)
	SUB B,UGOAL(C)
	MOVMS B
	CAIGE B,10.
	PUSHJ P,ULLP1	;TERM LOW PRIORITY DIRECTORY POS (COMMIT TO ACTUAL WRITE)
JDBRK6:	AOBJN C,JDBRK7
	MOVE C,UTTM3	;MOST PRESSING RUNNING UNIT
	MOVE B,UTTM2
	CAIGE B,30.
	JRST JDB7	;STAY WITH PRESSING UNIT
	SKIPE UTTM1
	JRST JDB5	;START UNIT IF POSSIBLE
JDF6A:	CAMG B,[10000000.]
	JRST JDB7
	AOSE UTTM4	;DON'T IF FLAP OP STILL IN PROGRESS
	PUSHJ P,JDDS
	SETOM UIDLE
	JRST POPRET

JDF1:	MOVE E,UDIRO(C)
	AOJE E,JDF1A
	TLNE E,100000
	JRST JDF2
JDF1A:	SKIPGE UGOAL(C)	;FLAPPING OP
	SKIPGE ULDCH(C)
	JRST JDF2
	SKIPE UDIR(C)
	SKIPG DG2(C)
	JRST .+2
	JRST JDF3A	;HAVE JUST READ IN TAPE POS
	TLNN B,100000
	JRST JDF3	;UNIT TO START FLAPPING (I.E. READ IN TAPE POS, THEN FLAP)
	LDB D,[4000,,B]
	TLNN B,100000
	JRST JDBRK6
	TLNN B,200000	;ABORT FLAPPING
	CAMG D,TIME
	JRST JDF4	;UNIT TO STOP FLAPPING
	SETOM UTTM4	;INDICATE FLAP OP STILL ACTIVE
	JRST JDBRK6

JDDS:	CONO DTC,10000	;DESELECT
	CLEARM SUNIT
	POPJ P,

JDSTP:	MOVEI A,430000
	SETZM UDIR(C)
	SETZM OUDIR(C)
JDCNN:	HRRZS C
	CAME C,SUNIT	;DIR CONO IN A TO UNIT IN C
	SKIPN SUNIT
	JRST JDSTP1
	PUSHJ P,JDDS
JDSTP1:	DPB C,[110300,,A]
	CONO DTC,(A)
	MOVEM C,SUNIT
	POPJ P,

JDF3:	MOVE A,UDIRO(C)	;WANT TO FLAP
	AOJE A,JDF3A1	;DIR NOT IN
	TLNE A,10000
	JRST JDF3A2	;TAPE IN UBLAT MODE (COMMENT USED TO SAY DIR ON WAY IN) (??)
	HRRZ A,ULDCH(C)
	LDB Q,[IOCH,,IOBFT(A)]
	CAIE Q,NUTIC+NUTOC
	JRST 4,.
	LDB Q,[IOLO,,IOBFT(A)]
	CAIE Q,(C)
	JRST 4,.
	PUSHJ P,IBRTN	;RETURN DIR BUFFER
JDF3A2:	SETOM UDIRO(C)
	SETZM UTASS(C)
JDF3A1:	SETOM UDPWF(C)
	SKIPGE DG2(C)
	JRST JDF6
JDF3A:	SETOM DG2(C)	;FLAP UNIT INC(KNOWING WHERE IT IS)
	MOVE E,EUPOS(C)
	IMULI E,50.	;50 MS/BLOCK
	IDIVI E,33.	;33 MS/(1/2 SEC)
	ADDI E,30.	;15 SECS EXTRA
	ADD E,TIME	;NET TIME TO STOP FLAPPING
	TLO E,100000
	DPB E,[4200,,UFLAPF(C)]
	LSH C,9.
	CONO DTC,130000(C)	;GO REVERSE
	PUSHJ P,JDDS
	JRST JDB3

JDF6:	HRRZS C
	SETOM UDIR(C)
	JRST JDB7

JDF4:	TLNE B,40000
	JRST JDF4A
	MOVEI A,230000	;A SHOT OF FOWARD
	PUSHJ P,JDCNN	;REEL WILL STOP
	AND B,[700000,,]
	ADD B,[40000,,2]
	ADD B,TIME
	MOVEM B,UFLAPF(C)
	JRST JDB3

JDF4A:	PUSHJ P,JDSTP
	CLEARM UFLAPF(C)
	CLEARM EUPOS(C)
	SETOM DG2(C)
	JRST JDF5
JDB5:	HRRZ C,UTTM1
	MOVE E,UGOAL(C)
	CAML E,EUPOS(C)
	SKIPA B,[1]
	MOVNI B,1
	MOVEM B,UDIR(C)
JDB7:	SKIPN B,UDIR(C)
	JRST 4,.	;NOT TRYING TO GO
	MOVEI A,DCCHN_3
	SKIPN SUNIT
	JRST DCGB1
	CAME C,SUNIT
	JRST DCGB2
	CAMN B,OUDIR(C)
	TRO A,40000	;INHIBIT START DELAY (SAME UNIT, SAME DIRECTION)
DCGB1:	MOVEM C,SUNIT
	MOVEM B,OUDIR(C)
	TRNN A,40000
	TRO A,30000
	DPB C,[110300,,A]
	XCT UTST2(B)
	CONO DTS,770000
	MOVE C,[JSR TAPE]
	MOVEM C,DCMLOC
	MOVEM C,DCMLOC+1
	MOVE C,[JRST PIPOS]
	MOVEM C,UTP1
	JRST POPRET

DCGB2:	PUSHJ P,JDDS
	JRST DCGB1

	CONO DTC,130200+UTCCHN+<DCCHN_3>(A)
UTST:	CONO DTC,430000+UTCCHN+<DCCHN_3>(A)
	CONO DTC,230200+UTCCHN+<DCCHN_3>(A)

	CONO DTC,130200+UTCCHN(A)
UTST1:	CONO DTC,430000+UTCCHN(A)
	CONO DTC,230200+UTCCHN(A)

	CONO DTC,100200+UTCCHN(A)
UTST2:	CONO DTC,400000+UTCCHN(A)
	CONO DTC,200200+UTCCHN(A)
};IFN NEWDTP
IFE NEWDTP,{

; T S UTAPE ROUTINES PI SERV (OLD UTAPE CONTROL)

JDENB==40000	;ENABLE JOB DONE (CONO UTC,)
20MSEN==5000	;20MS, ENABLED (")

TAPE:	0
UTP1:	0	;DATAI DC, OR JRST UTP3

BBLK

	SOS .-1
	AOSGE TAPCNT
	JRST 12,@TAPE


UTP3:	SKIPN WRITE
	CONO DC,0
	CONO DC,400000	;CLEAR PIA
	JRST 12,@TAPE

PIPOS:	CONSO DC,1000
	JRST PIPX
	SKIPN C,SUNIT
	JRST PIPOS8	;NO UNIT SELECTED?
	DATAI DC,B	;UNIT SELECTED, GET BLOCK NUMBER
	TDZE B,[1777#-1]	;CLEAR OUT GARBAGE IN BLOCK NUMBER WORD
	JRST PIPOS7	;GARBAGE THERE, BAD BLOCK NUMBER
	MOVEM B,EUPOS(C)	;STORE POSITION
	HRRZM C,DG2(C)	;SIGNAL EUPOS IS ACCURATE
	SKIPGE UGOAL(C)	;GOING SOMEWHERE?
	JRST PIPF1	;NO
	SUB B,UGOAL(C)	;GET CURRENT - DESIRED
	JUMPE B,PIPOS2	;JUMP IF THERE
	ADD B,UDIR(C)
	MOVMM B,UTENB
	SKIPGE ULDCH(C)
	JRST PIPOS3
	JUMPN B,PIPOS3
PIPOSL:	MOVE A,SUNITL	;HOLD DC
	MOVE B,UDIR(C)
	XCT UTST(B)
	CONO DC,4010+UTCCHN
PIPOS5:	JRST PIPX

PIPOS7:	AOS BDBLKC
	JRST PIPOSL

EBLK

BDBLKC:	0

BBLK

PIPOS3:	MOVE A,UDIR(C)
	LSH A,2
	SUB B,A
	XOR B,UDIR(C)
	MOVE A,SUNITL
	JUMPG B,PIPOS4	;GOING WRONG DIR
PIPF2:	TRO A,JDENB	;ENB JD SO NEXT BREAK TO UTC ON BLOCK
PIPOS6:	MOVE B,TIME
	MOVEM B,ULCTM(C)
	ADD B,UTENB
	MOVEM B,DRTM(C)
	MOVE B,UDIR(C)
	XCT  UTST(B)
PIPOS8:	CONO DC,0
	JRST PIPOS5



PIPF1:	MOVE A,SUNITL
	JRST PIPF2

PIPOS4:	CLEARM DG2(C)
	MOVNS UDIR(C)
	TRO A,6000
	JRST PIPOS6

PIPOS2:	HLRZ A,ULDCH(C)	;TAPE NOW POSITIONED
	SKIPL ULDCH(C)
	SKIPGE UTRAC(A)
	JRST PIPOS3	;CHANNEL LOCKED
	SETOM UTLDD(A)	;CHANNEL ACTUALLY LOADED TRANSFER IMMINENT
	AOS SMODE
	MOVE A,SUNITL
	MOVE B,UMEMAD(C)
	SKIPGE URDWR(C)
	TROA A,400
	TLZ B,(BLKO-BLKI)
	SKIPL UDIR(C)
	JRST TAPFOR
	TRO A,10000
	ADD B,[DATAI-BLKI 200]
	MOVEM B,UTP1
	MOVNI B,200
	MOVEM B,TAPCNT


TAP4:	CONO UTC,360300+UTCCHN(A)
	MOVE B,URDWR(C)
	MOVEM B,WRITE
	CONO DC,400000+DCCHN	;GIVE CHN FOR READ
	SKIPGE B
	CONO DC,3410+DCCHN
	JRST PIPX


TAPFOR:	HRRM B,TAPCNT
	HRRI B,TAPCNT
	MOVEM B,DCMLOC
	MOVE B,[-200,,UTP3]
	HRRM B,UTP1
	HLLM B,TAPCNT
	JRST TAP4

UTERR:	CONSZ UTC,4000	;CHECK TIME ENABLE
	CONSO UTS,20	;CHECK TIME FLAG
	JRST .+2
	JRST UTCB1	;ELIMINATE TIMING ERROR IF FLAG COMES ON
	CONI UTS,E
	SKIPL SMODE
	JRST UDATER	;DATA ERROR
	CONO DC,0
	SKIPN C,SUNIT
	JRST JDB3	;NO UNIT SELECTED, IGNORE ERROR
	SETOM DG2(C)
	SKIPL UFLAPF(C)
	JRST UTER6	;NOT FLAPPING
	CLEARM UFLAPF(C)	;ERROR WHILE FLAPPING, JUST FORGET ABOUT IT
	CLEARM EUPOS(C)
	CLEARM UDIR(C)
	JRST JDB3
UTER6:	AOS UTERP(C)	;INCREMENT ERROR COUNT
	HRLM E,UTERP(C)	;STORE UTS CONI
	MOVE B,UDIR(C)
	TRZ E,7650	;CLEAR RANDOMNESS, WRITE, PARITY ERROR
	JUMPE E,JDB3	;JUMP ON ONLY PARITY ERROR (IF ANYTHING), TRY AGAIN NOW
	TRNN E,2	;CHECK EOT FLAG
	JRST UTER1	;NOT SET
	MOVNS B,UDIR(C)	;EOT, WANT TO GO OTHER DIRECTION
	MOVEI A,0
	SKIPGE B
	MOVEI A,1103
	MOVEM A,EUPOS(C)	;STORE NEW ESTIMATED POSIION
	MOVE A,TIME
	MOVEM A,ULCTM(C)
	MOVEM A,DRTM(C)
UTER1:	JRST UTER3	;GIVE MAX DELAY

UDATER:	SETOM SMODE	;DATA ERROR, TRY REPOSITIONING
	HLRZ D,ULDCH(C)
	CLEARM UTLDD(D)
	JRST JDB3

UTCB0:	MOVE C,SUNIT
	CONSZ UTC,4000
	CONSO UTS,20
	JRST JDBRK	;NOT TIME FLAG
UTCB1:	MOVE A,SUNITL
	MOVE B,UDIR(C)
	AOSN UTHERR	;HANG UP ERROR SENT FOR SLOW CLOCK ROUTINE
	JRST UTERR
	AOSN USTSW
	JRST DCGBL1
	AOSN USTPF
	JRST JDB7D
	MOVEI C,0
	EXCH C,FLPUNT
	JUMPN C,JDF8
	EXCH C,STPUNT
	JUMPN C,JDB4B
	JRST JDB3


JDDT3:	MOVE A,EUPOS(C)
	SUB A,UGOAL(C)
	MOVMS E,A
	ADD A,TIME
	MOVEM A,DRTM(C)
	MOVE C,[-NUNITS,,1]
	MOVM B,DRTM(C)
	CAMGE B,TIME
	JRST JDB3	;SOMETHING ELSE DUE
	AOBJN C,.-3
	MOVE C,SUNIT
	MOVE B,UDIR(C)
	MOVE A,SUNITL
	SOJLE E,DCGBL1	;RELOADING FOR NEXT BLOCK
	JRST JDB3


ILLP:	MOVEM D,UGOAL(C)	;LOW PRIORITY POSIT ENTRY
	MOVSI A,(SETZ)
	IORM A,ULDCH(C)

UTDC:	SKIPGE UGOAL(C)
	POPJ P,	;UNIT IDLE
	SKIPGE DG2(C)
	JRST UTDC3
	MOVE A,EUPOS(C)	;ESTIMATE UNIT TIME AND UPDATE EUPOS
	SKIPG DG2(C)	;SKIP ON EXACT POS KNOWN
	SKIPN UDIR(C)	;SKIP ON UNIT RUNNING
	JRST UTDC4
	MOVE B,TIME
	SUBM B,ULCTM(C)
	EXCH B,ULCTM(C)
	IMUL B,UDIR(C)
	ADD A,B	;ACTUAL ESTIMATED POSITION
	MOVEM A,EUPOS(C)	;UPDATE EUPOS
UTDC4:	SUB A,UGOAL(C)
	MOVM B,A
	CAIG B,2
	JRST UTDC2
	ADD A,UDIR(C)
	MOVMS A�	
	CAMLE A,B
	SETZB A,B	;GOING WRONG DIR
UTDC2:	CAILE B,200.
	MOVEI B,200.	;LIMIT LONGEST DEAD RECKON
	ADD B,TIME
	MOVEM B,DRTM(C)
	POPJ P,

UTDC3:	MOVEI B,0	;NOT KNOWN EXACT POS REQUIRES IMMEDIATE ATTENTION
	JRST UTDC2

JDBRK:	CONSZ UTS,16	;CHECK PARITY ERROR, ILLOP, EOT
	JRST UTERR
JDBK1:	CONSZ UTS,1	;SKIP ON NO JOB DONE
	CONSZ DC,7
	JRST POPRET	;NO ERRS + HAS DC CHNL, GO AWAY
	SKIPL SMODE
	JRST JDDTA	;DATA MODE
	JUMPE C,JDB3	;POSITIONING, JUMP ON NO UNIT SELECTED
	MOVE A,UDIR(C)
	ADDM A,EUPOS(C)
	MOVE A,TIME
	MOVEM A,ULCTM(C)
	PUSHJ P,UTDC	;COMPUTE DELAY

JDB3:	CONO DC,0
	HRLOI B,177777
	MOVEM B,UTTM2
	SETOM UTTM3	;UNIT MOST URGENT
	CLEARM UTTM1	;UNIT COULD START
	SETOM UTTM4	;TAPE TO START FLAPPING
	SETOM UTTM5	;TAPE TO STOP FLAPPED
	MOVE C,[-NUNITS,,1]
JDBRK7:	SKIPGE B,UFLAPF(C)
	JRST JDF1	;FLAPPING OP
JDF2:	SKIPL ULDCH(C)	;SKIP ON LOW PRIOR POSIT
	SKIPGE UGOAL(C)
	JRST JDB6	;UNIT FREE
JDF2A:	SKIPGE DG2(C)
	SKIPN UDIR(C)
	JRST JDS1
	MOVEM C,UTTM1	;UNIT IS RUNNING BLIND (OR NOT RUNNING)
	JRST JDBRK6
JDS1:	SKIPE UDIR(C)
	JRST JDBRK4
	SKIPN UTTM1
	HRRZM C,UTTM1
	JRST JDBRK6
JDBRK4:	SKIPN UDIR(C)
	JRST ULLP	;TAPE MAY NOT BE RUNNING IF IDLE
	MOVE B,DRTM(C)
	SUB B,TIME
	MOVE E,B
	SUB E,UTTM2
	JUMPL B,JDCV1	;ALREADY OVERDUE
	MOVM D,E
	CAIG B,20.	;CONFLICT MORE THAN 20 BLKS AWAY
	CAIL D,20.	;THEY ARE SEPARETED BY 20 BLKS
	JRST JDCV1
	HRRZS C	;RELIEVE CONFLICT BY STOPPING UNIT DUE LATEST
	CAMG B,UTTM2
	HRRZ C,UTTM3
JDF5:	CAME C,SUNIT
	SKIPN SUNIT
	JRST JDB4B	;STOP UNIT
	MOVEM C,STPUNT
	JRST JDB7D	;DESLECT FIRST
JDCV1:	JUMPGE E,ULLP
	MOVEM B,UTTM2
	HRRZM C,UTTM3
ULLP:	SKIPL ULDCH(C)
	JRST JDBRK6
	MOVE B,TIME
	SUB B,ULCTM(C)
	IMUL B,UDIR(C)
	SKIPE DG2(C)
	MOVEI B,0
	ADD B,EUPOS(C)
	SUB B,UGOAL(C)
	MOVMS B
	CAIGE B,10.
	PUSHJ P,ULLP1	;TERM LOW PRIORITY DIRECTORY POS (COMMIT TO ACTUAL WRITE)



JDBRK6:	AOBJN C,JDBRK7
	MOVE C,UTTM3	;MOST PRESSING RUNNING UNIT
	MOVE B,UTTM2
	CAIGE B,30.
	JRST JDB7	;STAY WITH PRESSING UNIT
	SKIPE UTTM1
	JRST JDB5	;START UNIT IF POSSIBLE
	SKIPL D,UTTM4
	JRST JDF3
JDF6A:	SKIPL D,UTTM5
	JRST JDF4
	CAMG B,[10000000.]	;SKIP ON ALL TAPES IDLE
	JRST JDB7
	SKIPE SUNIT
	JRST JDB7D
	SETOM UIDLE	;NO UNIT SELECTED
	CONO UTC,0
	JRST POPRET

JDF1:	MOVE E,UDIRO(C)
	AOJE E,JDF1A
	TLNE E,100000
	JRST JDF2	;DONT FLAP IF DIR NOT WRITTEN
JDF1A:	SKIPGE UGOAL(C)
	SKIPGE ULDCH(C)
	JRST JDF2	;FILE DIR WRITE IN PROG
	SKIPE UDIR(C)
	SKIPG DG2(C)
	JRST .+2
	JRST JDF3A	;JUST READ IN TAPE POS
	TLNN B,100000
	HRRZM C,UTTM4	;UNIT TO START FLAPPING
	LDB D,[4100,,B]
	TLNN B,100000
	JRST JDBRK6
	TLNN B,200000	;ABORT FLAPPING
	CAMG D,TIME
	HRRZM C,UTTM5	;UNIT TO STOP FLAPPING
	JRST JDBRK6


JDF3:	MOVE C,D
	MOVE A,UDIRO(C)
	AOJE A,JDF3A1
	TLNE A,10000
	JRST JDF3A2
	HRRZ A,ULDCH(C)
	LDB Q,[IOCH,,IOBFT(A)]
	CAIE Q,NUTIC+NUTOC
	JRST 4,.
	LDB Q,[IOLO,,IOBFT(A)]
	CAIE Q,(C)
	JRST 4,.
	PUSHJ P,IBRTN
JDF3A2:	SETOM UDIRO(C)
	SETZM UTASS(C)
JDF3A1:	SETOM UDPWF(C)
	SKIPGE DG2(C)
	JRST JDF6
JDF3A:	SETOM DG2(C)
	MOVE E,EUPOS(C)
	IMULI E,50.
	IDIVI E,33.
	ADDI E,30.
	ADD E,TIME
	DPB E,[4100,,UFLAPF(C)]
	MOVSI E,100000
	IORM E,UFLAPF(C)
	SKIPE SUNIT
	CAMN C,SUNIT
	JRST JDF8
	MOVEM C,FLPUNT
	JRST JDB7D

JDF8:	LSH C,3
	CONO UTC,235000+UTCCHN(C)
	JRST JDF9

JDF6:	SKIPE SUNIT
	CAMN C,SUNIT
	JRST .+2
	JRST JDB7D
	SETOB B,UDIR(C)
	MOVEM C,SUNIT
	DPB C,[30300,,SUNITL]
	JRST JDF6B

JDF4:	MOVE C,D
	CLEARM UFLAPF(C)
	CLEARM EUPOS(C)
	JRST JDF5

JDB5:	HRRZ C,UTTM1
JDB7:	EXCH C,SUNIT	;SELECT UNIT IN C
	JUMPE C,JDB7A	;NO UNIT SELECTED
	CAMN C,SUNIT
	JRST JDB7A
	PUSHJ P,URLS
	JUMPGE E,JDB7E	;OK TO LEAVE IT ALONE, CLEAR SELECTION CYCLE
	SKIPN UDIR(C)
	JRST JDB7E
JDB4B:	HRRZM C,SUNIT	;ENTER UNIT STOPPING CYCLE
	DPB C,[30300,,SUNITL]
JDB4A:	MOVE A,SUNITL
	SKIPG UDIR(C)
	TRO A,10000
	CONO UTC,205000+UTCCHN(A)	;CLEAR GO BIT
	SKIPE DG2(C)
	JRST JDB4A1
	MOVE B,TIME
	SUB B,ULCTM(C)
	IMUL B,UDIR(C)
	ADDM B,EUPOS(C)
JDB4A1:	CLEARM UDIR(C)
	HRLOI B,177777
	MOVEM B,DRTM(C)
	SETOM DG2(C)
JDF9:	SETOM USTPF	;UNIT STOPPING CYCLE
	JRST POPRET

EBLK

USTPF:	0
STPUNT:	0	;UNIT TO STOP DUE TO CONFLICT

BBLK

JDB7E:	SKIPA A,C
JDB7D:	MOVE A,SUNIT
	JUMPE A,JDB7D1
	SKIPLE DG2(A)
	CLEARM DG2(A)
JDB7D1:	CLEARM SUNIT	;DESELECT CYCLE
	CONI UTC,A
	TRZ A,200070
	TRO A,5000
	CONO UTC,(A)
	JRST POPRET


JDB7A:	MOVE C,SUNIT
	MOVE A,EUPOS(C)
	SUB A,UDIR(C)
	SUB A,UDIR(C)
	MOVEI B,1
	CAML A,UGOAL(C)
	MOVNI B,1
	DPB C,[30300,,SUNITL]
	MOVE D,UDIR(C)
	MOVEM B,UDIR(C)
	CAME D,B
	JRST JDS4	;CHANGING DIR (OR STARTING), ALLOW RELAY DLYS
JDBK3A:	MOVE E,DRTM(C)
	SUB E,TIME
JDDT8:	MOVE A,SUNITL
IFN IMXP,[
	SKIPL IMPXF
	SUBI E,2
]
	SKIPGE E
	MOVEI E,0
	SKIPL D,DG2(C)
	CAIG E,2
	JRST JDB3B
	CAIGE E,20
	JUMPE D,JDB3B	;GETTING CLOSE READ BLOCK NO
JDB3A:
DCGBL2:	TRO A,JDENB
JDB8A:	XCT UTST(B)
	JRST POPRET



JDB3B:
DCGBL1:	XCT UTST(B)
	MOVE C,[JSR TAPE]
	MOVEM C,DCMLOC
	MOVEM C,DCMLOC+1
	MOVE C,[JRST UTP1]
	MOVEM C,UTP1
	CONO DC,4010+UTCCHN
	JRST POPRET



	CONO UTC,330200+UTCCHN(A)
UTST:	CONO UTC,5000+UTCCHN(A)
	CONO UTC,320200+UTCCHN(A)


JDS4:	JUMPN D,UTER3
	MOVE D,TIME
	MOVEM D,ULCTM(C)
JDF6B:	SETOM USTSW	;STARTING OUT
UTER3:	MOVE A,SUNITL	;PICK UP UNIT SELECT FIELD OF CONO
	TRO A,6000	;SET FOR MAXIMUM DELAY
	JRST JDB8A

URLS:	SKIPE E,UDIR(C)	;SKIPN ON UNIT NOT RUNNING
	SKIPG E,DG2(C)	;RELEASE UNIT IN C E HAS PREV STATE OF DG2
	POPJ P,
	JRST UTDC
};IFE NEWDTP
